package mx.com.sinformex.simbel.utils;

import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import mx.com.sinformex.simbel.db.eos.Report;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.tapestry5.StreamResponse;
import org.apache.tapestry5.services.Response;

/**
 * @author Oscar Ivan Hernandez Ventura [ oscar at sinformex dot com dot mx]
 *
 * @version $ Id : XmlStreamResponse.java , v 1.0 13/05/2009 angellore $
 */
public class XmlStreamResponse implements StreamResponse {
	
	private InputStream stream;
	private int currentPage;
	private String error;
	public static final String CONTENT_TYPE = "text/xml";
	private List<Map<String,Object>> rows;
	private final Log log = LogFactory.getLog(getClass());
	private final String[] charsToScape = {"'","/","<",">","&",""};

	public XmlStreamResponse(List<Map<String,Object>> rows, int page, String error) {
		this.rows = rows;
		currentPage = page;
		this.error = error;
		parseResults();
	}

	public String getContentType() {
		return CONTENT_TYPE;
	}

	public InputStream getStream() throws IOException {
		log.info(String.format("Returning %d bytes.", stream.available()));
		return stream;
	}

	public void prepareResponse(Response arg0) {
		//DO NOTHING YET
	}
	
	private void parseResults() {
		StringBuilder buffer = new StringBuilder();
		List<Map<String, Object>> _rows = null;

		buffer.append("<simbel>");
		buffer.append(String.format("<detail rows='%d' totalPages='%d' currentPage='%d' error='%s'/>", rows.size(), Math.round(Double.valueOf(rows.size()).doubleValue() / Double.valueOf(Report.ROWS_PER_PAGE).doubleValue()), currentPage,  error == null ? "" : error));
		
		if(rows.size() > 0) {
			Map<String, Object> row = rows.get(0);
			buffer.append("<header>");
			
			for(Iterator<String> iter = row.keySet().iterator() ; iter.hasNext() ; ) {
				String key = iter.next();
				buffer.append(String.format("<header-label value='%s'/>", key));		
			}
			
			buffer.append("</header>");
		}
		
		if(rows.size() > Report.ROWS_PER_PAGE) {
			int init = currentPage * Report.ROWS_PER_PAGE;
			int offset = (currentPage * Report.ROWS_PER_PAGE) + Report.ROWS_PER_PAGE;
			
			if(offset > rows.size()) {
				offset = rows.size();
			}
			
			log.info(String.format("Returning rows [%d-%d] of %d", init, offset, rows.size()));
			_rows = rows.subList(init, offset );
		} else {
			_rows = rows;
		}
		
		buffer.append("<rows>");
		
		for(Map<String, Object> row : _rows) {
			buffer.append("<row>");
			
			for(Iterator<String> iter = row.keySet().iterator() ; iter.hasNext() ; ) {
				String key = iter.next();
				Object value = row.get(key);
				
				if(value instanceof String) {
					for(String charToReplace : charsToScape) {
						value = ((String) value).replaceAll(charToReplace, "");
					}
				}
				
				buffer.append(String.format("<column name='%s' value='%s' />", key, value));
			}
			
			buffer.append("</row>");
		}
		buffer.append("</rows>");
		buffer.append("</simbel>");
		
		_rows = null;
		
		stream = new java.io.StringBufferInputStream(buffer.toString());
	}

}
